package com.lucien.framework.shiro.realm;

import com.lucien.common.utils.StringUtils;
import com.lucien.system.domain.SysUser;
import com.lucien.system.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @Author: Lucien
 * @Description: 同时开启身份验证和权限验证，需要继承 AuthorizingRealm
 * @Date: Created in 2021/5/2
 */
@SuppressWarnings("serial")
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService userService;

    /**
     * 限定Realm 只处理 UsernamePasswordToken
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前用户
        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();

        Set<String> roleSet = new HashSet<>();
        //查询数据库，获取用户的角色信息
        String role = userService.getRole(sysUser.getUsername()).getRole();
        System.out.println("shirorealm获取的用户角色"+role);
        roleSet.add(role);
        //查询数据库，获取用户的权限信息

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//        info.addRole(role);
        info.setRoles(roleSet);
//        info.setStringPermissions();

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
//        System.out.println("shirorealm===" + username);
        SysUser sysUser = userService.selectByUsername(username);

        if (StringUtils.isNull(sysUser)) {
            throw new UnknownAccountException("用户不存在");
        }

        if (sysUser.getIsLocked()){
            throw new LockedAccountException("该用户已被锁定,暂时无法登录！");
        }
//        System.out.println("shirorealm===" + sysUser.getPassword());
        //使用用户名作为盐值
        ByteSource credentialsSalt  = ByteSource.Util.bytes(username);
//        System.out.println("用户盐值==="+credentialsSalt);
//
//        System.out.println("更新用户盐值"+userService.updateUserSalt(username, credentialsSalt.toString()));
//        userService.updateUserSalt(username, credentialsSalt.toString());
        /**
         * 将获取到的用户数据封装成 AuthenticationInfo 对象返回，此处封装为 SimpleAuthenticationInfo 对象。
         *  参数1. 认证的实体信息，可以是从数据库中获取到的用户实体类对象或者用户名
         *  参数2. 查询获取到的登录密码
         *  参数3. 盐值
         *  参数4. 当前 Realm 对象的名称，直接调用父类的 getName() 方法即可
         */

        SimpleAuthenticationInfo info =
                new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), credentialsSalt, getName());
        return info;
    }
}
